import pandas as pd
from datetime import datetime
import logging
import os

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

class Soccer1X2DataLoader:
    """足球胜平负玩法数据加载器"""
    
    def __init__(self):
        # 定义胜平负玩法必需的核心字段
        self.required_fields = [
            'match_id', 'timestamp', 'home_team', 'away_team',
            'home_odds', 'draw_odds', 'away_odds', 'result'
        ]
        
        # 定义字段类型映射
        self.field_types = {
            'match_id': int,
            'timestamp': str,  # 后续会转换为datetime
            'home_team': str,
            'away_team': str,
            'home_odds': float,
            'draw_odds': float,
            'away_odds': float,
            'result': str
        }
    
    def load_csv(self, file_path):
        """
        加载CSV格式的足球胜平负数据
        
        参数:
            file_path (str): CSV文件路径
            
        返回:
            pandas.DataFrame: 加载并处理后的数据集，None表示加载失败
        """
        # 验证文件是否存在
        if not os.path.exists(file_path):
            logger.error(f"文件不存在: {file_path}")
            return None
            
        try:
            # 读取CSV文件
            logger.info(f"开始加载数据: {file_path}")
            df = pd.read_csv(file_path)
            
            # 检查必需字段
            missing_fields = [field for field in self.required_fields if field not in df.columns]
            if missing_fields:
                logger.error(f"缺少必需字段: {', '.join(missing_fields)}")
                return None
            
            # 只保留需要的字段
            df = df[self.required_fields].copy()
            
            # 转换字段类型
            for field, dtype in self.field_types.items():
                if field == 'timestamp':
                    # 特殊处理时间戳
                    try:
                        df[field] = pd.to_datetime(df[field], format='%Y-%m-%d %H:%M')
                    except ValueError:
                        logger.error(f"时间戳格式错误，应为'YYYY-MM-DD HH:MM'")
                        return None
                else:
                    try:
                        df[field] = df[field].astype(dtype)
                    except ValueError:
                        logger.error(f"字段 {field} 类型转换失败，期望类型: {dtype}")
                        return None
            
            # 验证result字段值是否合法
            valid_results = {'1', 'X', '2'}
            invalid_results = df[~df['result'].isin(valid_results)]
            if not invalid_results.empty:
                logger.warning(f"发现{len(invalid_results)}条无效结果记录，已过滤")
                df = df[df['result'].isin(valid_results)]
            
            # 按时间戳排序
            df = df.sort_values('timestamp').reset_index(drop=True)
            
            logger.info(f"数据加载完成，共 {len(df)} 条有效记录")
            return df
            
        except Exception as e:
            logger.error(f"数据加载失败: {str(e)}")
            return None

# 生成测试数据
def generate_test_data(file_path='soccer_test_data.csv'):
    """生成10条测试数据用于验证"""
    data = [
        {
            'match_id': 1,
            'timestamp': '2023-10-01 15:00',
            'home_team': 'Manchester United',
            'away_team': 'Liverpool',
            'home_odds': 2.50,
            'draw_odds': 3.20,
            'away_odds': 2.80,
            'result': '1'
        },
        {
            'match_id': 2,
            'timestamp': '2023-10-01 17:30',
            'home_team': 'Chelsea',
            'away_team': 'Arsenal',
            'home_odds': 2.20,
            'draw_odds': 3.40,
            'away_odds': 3.10,
            'result': 'X'
        },
        {
            'match_id': 3,
            'timestamp': '2023-10-02 12:00',
            'home_team': 'Barcelona',
            'away_team': 'Real Madrid',
            'home_odds': 2.10,
            'draw_odds': 3.50,
            'away_odds': 3.30,
            'result': '2'
        },
        {
            'match_id': 4,
            'timestamp': '2023-10-02 14:45',
            'home_team': 'Bayern Munich',
            'away_team': 'Dortmund',
            'home_odds': 1.80,
            'draw_odds': 3.70,
            'away_odds': 4.50,
            'result': '1'
        },
        {
            'match_id': 5,
            'timestamp': '2023-10-03 16:00',
            'home_team': 'Juventus',
            'away_team': 'Inter Milan',
            'home_odds': 2.30,
            'draw_odds': 3.30,
            'away_odds': 3.00,
            'result': 'X'
        },
        {
            'match_id': 6,
            'timestamp': '2023-10-04 13:30',
            'home_team': 'Paris Saint-Germain',
            'away_team': 'Marseille',
            'home_odds': 1.60,
            'draw_odds': 4.00,
            'away_odds': 5.50,
            'result': '1'
        },
        {
            'match_id': 7,
            'timestamp': '2023-10-04 19:00',
            'home_team': 'Manchester City',
            'away_team': 'Tottenham',
            'home_odds': 1.90,
            'draw_odds': 3.60,
            'away_odds': 4.20,
            'result': '2'
        },
        {
            'match_id': 8,
            'timestamp': '2023-10-05 15:00',
            'home_team': 'AC Milan',
            'away_team': 'Napoli',
            'home_odds': 2.40,
            'draw_odds': 3.20,
            'away_odds': 2.90,
            'result': '1'
        },
        {
            'match_id': 9,
            'timestamp': '2023-10-05 18:00',
            'home_team': 'Atletico Madrid',
            'away_team': 'Sevilla',
            'home_odds': 2.00,
            'draw_odds': 3.40,
            'away_odds': 3.60,
            'result': 'X'
        },
        {
            'match_id': 10,
            'timestamp': '2023-10-06 16:30',
            'home_team': 'Borussia Monchengladbach',
            'away_team': 'RB Leipzig',
            'home_odds': 3.10,
            'draw_odds': 3.50,
            'away_odds': 2.20,
            'result': '2'
        },
        {
            'match_id': 11,
            'timestamp': '2023-10-06 16:30',
            'home_team': 'MonchengladbachBorussia ',
            'away_team': 'RB Leipzig',
            'home_odds': 3.90,
            'draw_odds': 3.50,
            'away_odds': 1.20,
            'result': '2'
        }
    ]
    
    # 创建DataFrame并保存为CSV
    df = pd.DataFrame(data)
    df.to_csv(file_path, index=False)
    logger.info(f"已生成10条测试数据到 {file_path}")
    return file_path

# 测试函数
def test_data_loading():
    """测试数据加载功能"""
    # 生成测试数据
    test_file = generate_test_data()
    
    # 创建数据加载器
    loader = Soccer1X2DataLoader()
    
    # 加载数据
    df = loader.load_csv(test_file)
    
    if df is not None:
        print("\n===== 加载的数据预览 =====")
        print(df.head())
        
        print("\n===== 数据信息 =====")
        print(f"记录数: {len(df)}")
        print("\n数据类型:")
        print(df.dtypes)
        
        print("\n===== 时间戳排序验证 =====")
        print("时间戳顺序:")
        print(df['timestamp'].tolist())

if __name__ == "__main__":
    test_data_loading()
